#!/usr/bin/env python3
"""
商品管理API
提供商品相关的CRUD操作和文件上传功能
"""

from typing import List, Optional
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from sqlmodel import select, and_
from database.connection import get_session
from database.models import Product, Category, ProductImage, Model3D, User, UserRole, Model3DStatus
from validators.product_validator import (
    ProductCreate, ProductUpdate, ProductResponse, 
    ProductImageUpload, CategoryCreate, CategoryUpdate
)
from utils.file_upload import get_file_manager
from services.shopify_service import shopify_service
import json


router = APIRouter(prefix="/api/products", tags=["商品管理"])


@router.get("/", response_model=List[ProductResponse])
async def get_products(
    skip: int = 0,
    limit: int = 100,
    category_id: Optional[int] = None,
    search: Optional[str] = None,
    is_active: Optional[bool] = None,
    session: AsyncSession = Depends(get_session)
):
    """获取商品列表"""
    query = select(Product).options(selectinload(Product.category))
    
    # 应用筛选条件
    if category_id:
        query = query.where(Product.category_id == category_id)
    
    if is_active is not None:
        query = query.where(Product.is_active == is_active)
    
    if search:
        query = query.where(
            and_(
                Product.name.contains(search),
                Product.description.contains(search)
            )
        )
    
    # 排序和分页
    query = query.order_by(Product.created_at.desc())
    query = query.offset(skip).limit(limit)
    
    result = await session.execute(query)
    products = result.scalars().all()
    
    # 手动格式化日期时间字段和处理available_materials字段
    for product in products:
        if hasattr(product, 'created_at') and product.created_at:
            product.created_at = product.created_at.isoformat()
        if hasattr(product, 'updated_at') and product.updated_at:
            product.updated_at = product.updated_at.isoformat()
        
        # 处理available_materials字段 - 从JSON字符串转换为列表
        if hasattr(product, 'available_materials') and product.available_materials:
            try:
                product.available_materials = json.loads(product.available_materials)
            except (json.JSONDecodeError, TypeError):
                # 如果解析失败，设置为空列表
                product.available_materials = []
        else:
            product.available_materials = []
    
    return products


@router.get("/{product_id}", response_model=ProductResponse)
async def get_product(
    product_id: int,
    session: AsyncSession = Depends(get_session)
):
    """获取单个商品详情"""
    result = await session.execute(
        select(Product)
        .options(selectinload(Product.category))
        .where(Product.id == product_id)
    )
    product = result.scalar_one_or_none()
    
    if not product:
        raise HTTPException(status_code=404, detail="商品不存在")
    
    # 处理available_materials字段 - 从JSON字符串转换为列表
    if hasattr(product, 'available_materials') and product.available_materials:
        try:
            product.available_materials = json.loads(product.available_materials)
        except (json.JSONDecodeError, TypeError):
            # 如果解析失败，设置为空列表
            product.available_materials = []
    else:
        product.available_materials = []
    
    # 处理available_materials字段 - 从JSON字符串转换为列表
    if hasattr(product, 'available_materials') and product.available_materials:
        try:
            product.available_materials = json.loads(product.available_materials)
        except (json.JSONDecodeError, TypeError):
            # 如果解析失败，设置为空列表
            product.available_materials = []
    else:
        product.available_materials = []
    
    # 手动格式化日期时间字段
    if hasattr(product, 'created_at') and product.created_at:
        product.created_at = product.created_at.isoformat()
    if hasattr(product, 'updated_at') and product.updated_at:
        product.updated_at = product.updated_at.isoformat()
    
    return product


@router.post("/", response_model=ProductResponse)
async def create_product(
    product: ProductCreate,
    session: AsyncSession = Depends(get_session)
):
    """创建新商品"""
    # 检查分类是否存在
    result = await session.execute(select(Category).where(Category.id == product.category_id))
    category = result.scalar_one_or_none()
    
    if not category:
        raise HTTPException(status_code=400, detail="商品分类不存在")
    
    # 创建商品
    product_data = product.dict()
    
    # 处理available_materials字段 - 转换为JSON字符串存储
    if 'available_materials' in product_data and product_data['available_materials'] is not None:
        product_data['available_materials'] = json.dumps(product_data['available_materials'])
    
    db_product = Product(
        **product_data
    )
    
    session.add(db_product)
    await session.commit()
    await session.refresh(db_product)
    
    # 同步到Shopify（如果启用）
    try:
        shopify_result = await shopify_service.create_product(db_product)
        if shopify_result and shopify_result.get('id'):
            # 保存Shopify产品ID到系统中
            db_product.shopify_product_id = shopify_result['id']
            if shopify_result.get('variants') and len(shopify_result['variants']) > 0:
                db_product.shopify_variant_id = shopify_result['variants'][0].get('id')
            await session.commit()
            await session.refresh(db_product)
    except Exception as e:
        print(f"Shopify同步失败: {e}")
    
    # 处理available_materials字段 - 从JSON字符串转换为列表
    if hasattr(db_product, 'available_materials') and db_product.available_materials:
        try:
            db_product.available_materials = json.loads(db_product.available_materials)
        except (json.JSONDecodeError, TypeError):
            # 如果解析失败，设置为空列表
            db_product.available_materials = []
    else:
        db_product.available_materials = []
    
    # 手动格式化日期时间字段
    if hasattr(db_product, 'created_at') and db_product.created_at:
        db_product.created_at = db_product.created_at.isoformat()
    if hasattr(db_product, 'updated_at') and db_product.updated_at:
        db_product.updated_at = db_product.updated_at.isoformat()
    
    return db_product


@router.put("/{product_id}", response_model=ProductResponse)
async def update_product(
    product_id: int,
    product_update: ProductUpdate,
    session: AsyncSession = Depends(get_session)
):
    """更新商品信息"""
    result = await session.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    
    if not product:
        raise HTTPException(status_code=404, detail="商品不存在")
    
    # 更新字段
    update_data = product_update.dict(exclude_unset=True)
    
    # 处理available_materials字段 - 转换为JSON字符串存储
    if 'available_materials' in update_data and update_data['available_materials'] is not None:
        update_data['available_materials'] = json.dumps(update_data['available_materials'])
    
    for field, value in update_data.items():
        setattr(product, field, value)
    
    product.updated_at = datetime.utcnow()
    
    await session.commit()
    await session.refresh(product)
    
    # 同步更新到Shopify
    try:
        await shopify_service.update_product(product)
    except Exception as e:
        print(f"Shopify同步更新失败: {e}")
    
    # 手动格式化日期时间字段
    if hasattr(product, 'created_at') and product.created_at:
        product.created_at = product.created_at.isoformat()
    if hasattr(product, 'updated_at') and product.updated_at:
        product.updated_at = product.updated_at.isoformat()
    
    return product


@router.delete("/{product_id}")
async def delete_product(
    product_id: int,
    session: AsyncSession = Depends(get_session)
):
    """删除商品"""
    result = await session.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    
    if not product:
        raise HTTPException(status_code=404, detail="商品不存在")
    
    # 从Shopify删除（如果存在）
    try:
        await shopify_service.delete_product(product.shopify_product_id)
    except Exception as e:
        print(f"Shopify删除失败: {e}")
    
    await session.delete(product)
    await session.commit()
    
    return {"message": "商品删除成功"}


@router.post("/{product_id}/images")
async def upload_product_image(
    product_id: int,
    image: UploadFile = File(...),
    alt_text: Optional[str] = Form(None),
    is_primary: bool = Form(False),
    session: AsyncSession = Depends(get_session)
):
    """上传商品图片"""
    # 检查商品是否存在
    result = await session.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    
    if not product:
        raise HTTPException(status_code=404, detail="商品不存在")
    
    # 上传文件
    file_manager = get_file_manager()
    upload_result = await file_manager.save_image_file(image, f"products/{product_id}")
    
    # 如果设置为primary，先取消其他图片的primary状态
    if is_primary:
        await session.execute(
            select(ProductImage)
            .where(ProductImage.product_id == product_id)
            .where(ProductImage.is_primary == True)
        )
        # 更新其他图片为非primary
        result = await session.execute(
            select(ProductImage)
            .where(ProductImage.product_id == product_id)
            .where(ProductImage.is_primary == True)
        )
        primary_images = result.scalars().all()
        for img in primary_images:
            img.is_primary = False
    
    # 创建图片记录
    product_image = ProductImage(
        product_id=product_id,
        image_url=upload_result['url'],
        alt_text=alt_text or f"{product.name} 图片",
        is_primary=is_primary,
        sort_order=1
    )
    
    session.add(product_image)
    await session.commit()
    await session.refresh(product_image)
    
    return product_image


@router.post("/{product_id}/3d-models")
async def upload_3d_model(
    product_id: int,
    model_file: UploadFile = File(...),
    description: Optional[str] = Form(None),
    session: AsyncSession = Depends(get_session)
):
    """上传3D模型文件"""
    # 检查商品是否存在
    result = await session.execute(select(Product).where(Product.id == product_id))
    product = result.scalar_one_or_none()
    
    if not product:
        raise HTTPException(status_code=404, detail="商品不存在")
    
    # 上传文件
    file_manager = get_file_manager()
    upload_result = await file_manager.save_3d_model_file(model_file, f"products/{product_id}")
    
    # 创建3D模型记录
    model_3d = Model3D(
        product_id=product_id,
        source_image_id=1,  # 临时使用1作为默认图片ID，实际应该关联到具体的商品图片
        model_file_url=upload_result['url'],
        file_format=upload_result['format'],
        file_size=int(upload_result['file_size']),
        original_filename=model_file.filename,
        storage_path=upload_result['file_path'],
        status="pending",  # 使用字符串状态值
        description=description,
        version=1
    )
    
    session.add(model_3d)
    await session.commit()
    await session.refresh(model_3d)
    
    # 同步到Shopify（如果启用）
    try:
        shopify_result = await shopify_service.upload_3d_model(product, model_3d)
        if shopify_result:
            # 保存Shopify相关ID到模型记录
            model_3d.shopify_asset_id = shopify_result.get('asset_id')
            model_3d.shopify_asset_url = shopify_result.get('asset_url')
            model_3d.shopify_metafield_id = shopify_result.get('metafield_id')
            model_3d.shopify_product_id = product.shopify_product_id
            model_3d.shopify_variant_id = product.shopify_variant_id
            await session.commit()
            await session.refresh(model_3d)
    except Exception as e:
        print(f"Shopify 3D模型同步失败: {e}")
    
    return model_3d


@router.get("/{product_id}/images")
async def get_product_images(
    product_id: int,
    session: AsyncSession = Depends(get_session)
):
    """获取商品图片列表"""
    result = await session.execute(
        select(ProductImage)
        .where(ProductImage.product_id == product_id)
        .order_by(ProductImage.is_primary.desc(), ProductImage.sort_order)
    )
    images = result.scalars().all()
    
    return images


@router.get("/{product_id}/3d-models")
async def get_product_3d_models(
    product_id: int,
    session: AsyncSession = Depends(get_session)
):
    """获取商品3D模型列表"""
    result = await session.execute(
        select(Model3D)
        .where(Model3D.product_id == product_id)
        .order_by(Model3D.created_at.desc())
    )
    models = result.scalars().all()
    
    return models


# 商品分类管理
@router.get("/categories/", response_model=List[dict])
async def get_categories(
    is_active: Optional[bool] = None,
    session: AsyncSession = Depends(get_session)
):
    """获取商品分类列表"""
    query = select(Category)
    
    if is_active is not None:
        query = query.where(Category.is_active == is_active)
    
    query = query.order_by(Category.sort_order, Category.name)
    
    result = await session.execute(query)
    categories = result.scalars().all()
    
    return [category.dict() for category in categories]


@router.post("/categories/")
async def create_category(
    category: CategoryCreate,
    session: AsyncSession = Depends(get_session)
):
    """创建商品分类"""
    db_category = Category(**category.dict())
    
    session.add(db_category)
    await session.commit()
    await session.refresh(db_category)
    
    return db_category


@router.put("/categories/{category_id}")
async def update_category(
    category_id: int,
    category_update: CategoryUpdate,
    session: AsyncSession = Depends(get_session)
):
    """更新商品分类"""
    result = await session.execute(select(Category).where(Category.id == category_id))
    category = result.scalar_one_or_none()
    
    if not category:
        raise HTTPException(status_code=404, detail="分类不存在")
    
    update_data = category_update.dict(exclude_unset=True)
    
    for field, value in update_data.items():
        setattr(category, field, value)
    
    await session.commit()
    await session.refresh(category)
    
    return category


@router.delete("/categories/{category_id}")
async def delete_category(
    category_id: int,
    session: AsyncSession = Depends(get_session)
):
    """删除商品分类"""
    result = await session.execute(select(Category).where(Category.id == category_id))
    category = result.scalar_one_or_none()
    
    if not category:
        raise HTTPException(status_code=404, detail="分类不存在")
    
    # 检查是否有商品使用该分类
    result = await session.execute(select(Product).where(Product.category_id == category_id).limit(1))
    existing_product = result.scalar_one_or_none()
    
    if existing_product:
        raise HTTPException(status_code=400, detail="该分类下存在商品，无法删除")
    
    await session.delete(category)
    await session.commit()
    
    return {"message": "分类删除成功"}


@router.post("/sync-shopify", response_model=dict)
async def sync_products_from_shopify(
    session: AsyncSession = Depends(get_session)
):
    """从Shopify同步商品数据到系统"""
    try:
        # 调用Shopify服务同步数据
        synced_products = await shopify_service.sync_products_from_shopify()
        
        # 处理同步的商品数据
        new_products_count = 0
        updated_products_count = 0
        
        for shopify_product in synced_products:
            # 查找是否已存在对应商品
            result = await session.execute(
                select(Product).where(Product.shopify_product_id == str(shopify_product['id']))
            )
            existing_product = result.scalar_one_or_none()
            
            if not existing_product:
                # 创建新商品
                print(f"检测到新的Shopify商品: {shopify_product.get('title', '未知商品')}")
                
                # 创建新商品实例
                new_product = Product(
                    name=shopify_product.get('title', '未知商品'),
                    description=shopify_product.get('body_html', ''),
                    price=float(shopify_product.get('price', '0.00')),
                    stock_quantity=0,  # 默认库存为0
                    is_active=shopify_product.get('status') == 'active',
                    shopify_product_id=str(shopify_product['id']),
                    created_at=datetime.fromisoformat(shopify_product.get('created_at', datetime.now().isoformat())),
                    updated_at=datetime.fromisoformat(shopify_product.get('updated_at', datetime.now().isoformat()))
                )
                
                # 处理变体信息
                if 'variants' in shopify_product and shopify_product['variants']:
                    first_variant = shopify_product['variants'][0]
                    new_product.shopify_variant_id = str(first_variant.get('id', ''))
                    new_product.price = float(first_variant.get('price', '0.00'))
                    new_product.stock_quantity = first_variant.get('inventory_quantity', 0)
                
                # 保存到数据库
                session.add(new_product)
                await session.commit()
                await session.refresh(new_product)
                new_products_count += 1
                
                # 处理商品图片
                if 'images' in shopify_product and shopify_product['images']:
                    for img_data in shopify_product['images']:
                        # 这里应该有实际的图片下载和保存逻辑
                        # 简化处理，仅记录图片URL
                        img_url = img_data.get('src', '')
                        if img_url:
                            # 创建图片记录
                            product_image = ProductImage(
                                product_id=new_product.id,
                                uploader_id=1,  # 默认为系统用户
                                image_url=img_url,
                                is_primary=img_data.get('position') == 1
                            )
                            session.add(product_image)
                    await session.commit()
            else:
                # 更新现有商品
                print(f"更新现有Shopify商品: {shopify_product.get('title', '未知商品')}")
                
                # 更新基本信息
                existing_product.name = shopify_product.get('title', existing_product.name)
                existing_product.description = shopify_product.get('body_html', existing_product.description)
                existing_product.is_active = shopify_product.get('status') == 'active'
                existing_product.updated_at = datetime.fromisoformat(shopify_product.get('updated_at', datetime.now().isoformat()))
                
                # 更新变体信息
                if 'variants' in shopify_product and shopify_product['variants']:
                    first_variant = shopify_product['variants'][0]
                    existing_product.price = float(first_variant.get('price', str(existing_product.price)))
                    existing_product.stock_quantity = first_variant.get('inventory_quantity', existing_product.stock_quantity)
                
                await session.commit()
                updated_products_count += 1
        
        return {
            "status": "success",
            "message": "Shopify商品同步完成",
            "synced_count": len(synced_products),
            "new_products": new_products_count,
            "updated_products": updated_products_count
        }
        
    except Exception as e:
        print(f"Shopify商品同步异常: {e}")
        # 发生异常时回滚会话
        await session.rollback()
        raise HTTPException(status_code=500, detail=f"同步失败: {str(e)}")